//
//  SpeechManager.m
//  SDKSample
//
//  Created by niren on 2023/2/15.
//

#import "YZXfSpeechManager.h"

@interface YZXfSpeechManager ()<IFlySpeechRecognizerDelegate>
@property (nonatomic, strong) IFlySpeechRecognizer *recognizer;
@property (nonatomic, copy) NSString *resultText;
@property (nonatomic, copy) YZSpeechCompletion stopCompletion;
@property (nonatomic, copy) YZSpeechCancel cancelCompletion;
@end

@implementation YZXfSpeechManager

+ (YZXfSpeechManager *)sharedManager {
    static YZXfSpeechManager *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [YZXfSpeechManager new];
    });
    return instance;
}

- (void)initSDKWithAppid:(NSString *)appid {
#if DEBUG
    [IFlySetting showLogcat:NO];
    [IFlySetting setLogFile:LVL_ALL];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *cachePath = [paths objectAtIndex:0];
    [IFlySetting setLogFilePath:cachePath];
#endif
    // TODO: 配置讯飞平台的appid
    if(appid == NULL) appid = @"12cece45";
    // 异步初始化
    [IFlySpeechUtility createUtility:[NSString stringWithFormat:@"appid=%@",appid]];
}

- (IFlySpeechRecognizer *)recognizer {
    if (!_recognizer) {
        _recognizer = [IFlySpeechRecognizer sharedInstance];
        _recognizer.delegate = self;
    }
    return _recognizer;
}

- (void)setDefaultRecognizerMode {
    // 设置为听写模式
    [self.recognizer setParameter:@"iat" forKey:[IFlySpeechConstant IFLY_DOMAIN]];
    //asr_audio_path 是录音文件名，设置value为nil或者为空取消保存，默认保存目录在Library/cache下。
    [self.recognizer setParameter:@"iat.pcm" forKey:[IFlySpeechConstant ASR_AUDIO_PATH]];
    // 直接返回自然语言
    [self.recognizer setParameter:@"plain" forKey:[IFlySpeechConstant RESULT_TYPE]];
}

- (BOOL)isListening {
    return self.recognizer.isListening;
}

- (void)resetResults {
    self.resultText = nil;
    self.stopCompletion = nil;
}

- (void)startListening {
    if (self.isListening) {
        return;
    }
    [self resetResults];
    [self.recognizer startListening];
}

- (void)stopListening:(YZSpeechCompletion)completion {
    self.stopCompletion = completion;
    if (!self.isListening) {
        // 注意这里可能提前结束的
        if (self.stopCompletion != nil) {
            self.stopCompletion(self.resultText);
        }
    }
    [self.recognizer stopListening];
}

- (void)cancel:(YZSpeechCancel)completion {
    [self resetResults];
    self.cancelCompletion = completion;
    [self.recognizer cancel];
}

- (NSString *)parseSpeechResults:(NSArray *)results {
    NSMutableString *result = [[NSMutableString alloc] init];
    if (results != nil) {
        NSDictionary *dic = [results objectAtIndex:0];
        for (NSString *key in dic){
           [result appendFormat:@"%@",key];
        }
    }
    return result.copy;
}

#pragma mark - IFlySpeechRecognizerDelegate

/*!
 * 录音开始
 */
- (void)onBeginOfSpeech {
    if ([_delegate respondsToSelector:@selector(onBeginOfSpeech)]) {
        [_delegate onBeginOfSpeech];
    }
}

/*!
 * 录音结束
 */
- (void)onEndOfSpeech {
    if ([_delegate respondsToSelector:@selector(onEndOfSpeech)]) {
        [_delegate onEndOfSpeech];
    }
}

- (void)onCancel {
    if (self.cancelCompletion != nil) {
        self.cancelCompletion();
    }
}

- (void)onCompleted:(IFlySpeechError *)error {
    NSLog(@"IFlySpeech onCompleted: %@, code: %d",error.errorDesc, error.errorCode);
    
    if ([_delegate respondsToSelector:@selector(onCompleted:)]) {
        [_delegate onCompleted:error];
    }
}

- (void)onResults:(NSArray *)results isLast:(BOOL)isLast {
    if (self.resultText == nil) {
        self.resultText = [self parseSpeechResults:results];
    } else {
        self.resultText = [self.resultText stringByAppendingString:[self parseSpeechResults:results]];
    }
    if (isLast) {
        if (self.stopCompletion != nil) {
            self.stopCompletion(self.resultText);
        }
    }
    
    NSString *res = self.resultText;
    if (res == nil || results == nil) {
        res = @"";
        isLast = true;
        results = @[];
    }
    
    if ([_delegate respondsToSelector:@selector(onResults:isLast:parseText:)]) {
        [_delegate onResults:results isLast:isLast parseText:self.resultText];
    }
}

@end
